package com.kelaite.procurement.service.impl;

import io.jsonwebtoken.lang.Collections;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kelaite.procurement.constants.Constants;
import com.kelaite.procurement.dto.UserDTO;
import com.kelaite.procurement.dto.VendorDTO;
import com.kelaite.procurement.dto.VendorUserDTO;
import com.kelaite.procurement.entity.TUser;
import com.kelaite.procurement.entity.TVendor;
import com.kelaite.procurement.entity.TVendorUser;
import com.kelaite.procurement.exception.BusinessException;
import com.kelaite.procurement.repository.VendorUserRepository;
import com.kelaite.procurement.service.VendorUserService;
import com.kelaite.procurement.utils.ConvertUtil;

@Service
@Transactional
public class VendorUserServiceImpl implements VendorUserService {

	@Autowired
	private VendorUserRepository vendorUserRepository;

	@PersistenceContext
	private EntityManager em;

	@Override
	public TVendorUser save(TVendorUser persistence) {
		return this.vendorUserRepository.save(persistence);
	}

	@Override
	public TVendorUser getObject(Long id) {
		return this.vendorUserRepository.findOne(id);
	}

	@Override
	public List<TVendorUser> getAll() {
		return this.vendorUserRepository.findAll();
	}

	@Override
	public void deleteByObject(TVendorUser persistence) {
		this.vendorUserRepository.delete(persistence);
	}

	@Override
	public void deleteByPrimaryKey(Long id) {
		this.vendorUserRepository.delete(id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<TVendorUser> getByProperty(String property, Object value) {
		Session session = (org.hibernate.Session) em.getDelegate();
		Criteria criteria = session.createCriteria(TVendorUser.class).add(
				Restrictions.eq(property, value));
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<TVendorUser> getUsersByVendorOfSupplier(TVendor vendor) {
		Session session = (org.hibernate.Session) em.getDelegate();
		List<TVendorUser> vendorUsers = session
				.createCriteria(TVendorUser.class)
				.add(Restrictions.eq("tVendor", vendor))
				.add(Restrictions.eq("businessType", Constants.COMPANY_BUSINESS_TYPE_PARTY_SECOND))
				.addOrder(Order.asc("id")).list();

		return vendorUsers;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<TVendorUser> getUserByVendorOfSupplierAndUser(TVendor vendor,
			TUser user) {
		Session session = (org.hibernate.Session) em.getDelegate();
		List<TVendorUser> vendorUsers = session
				.createCriteria(TVendorUser.class)
				.add(Restrictions.eq("tVendor", vendor))
				.add(Restrictions.eq("tUser", user))
				.add(Restrictions.eq("businessType",
						Constants.COMPANY_BUSINESS_TYPE_PARTY_SECOND))
				.addOrder(Order.asc("id")).list();
		return vendorUsers;
	}

	@Override
	public List<VendorUserDTO> getByTVendorAndBusinessTypeAndStatus(
			VendorDTO tVendor, Integer businessType, Integer status) {
		if(null == tVendor || null == tVendor.getId()){
			throw new BusinessException("vendor object is null or invalid! ");
		}
		 List<TVendorUser> dbList = vendorUserRepository.findByTVendorAndBusinessTypeAndStatus(ConvertUtil.convertObj(tVendor, TVendor.class), businessType, status);
		 //
		 List<VendorUserDTO> dtoList = new ArrayList<VendorUserDTO>();
		 if(!Collections.isEmpty(dbList)){
			 for(TVendorUser dbVendorUser : dbList){
				 VendorUserDTO vendorUserDto = ConvertUtil.convertObj(dbVendorUser, VendorUserDTO.class);
				 vendorUserDto.settUser(ConvertUtil.convertObj(dbVendorUser.gettUser(), UserDTO.class));
				 vendorUserDto.settVendor(tVendor);
				 dtoList.add(vendorUserDto);
			 }
		 }
		return dtoList;
	}
}
